/**
 * @file qq.h
 *
 */
#ifndef QQ_H
#define QQ_H

#ifdef __cplusplus
extern "C" {
#endif

/*********************
 *      INCLUDES
 *********************/

#ifdef LV_CONF_INCLUDE_SIMPLE
#include "lvgl.h"
#include "lv_watch_conf.h"
#else
#include "../../../lvgl/lvgl.h"
#include "../../../lv_watch_conf.h"
#endif

#if USE_LV_WATCH_QQ != 0

#include "net/ui_net_interface.h"
#include "qq_data_interface.h"
/*********************
 *      DEFINES
*********************/
#define QQ_UI_TEST 0

#if LV_WATCH_SIMULATOR_360 != 0
#define QQ_PAD_HOR 30
#define QQ_PAD_VER 20
#define QQ_BACK_IMG_PAD_LEFT 80
#else
#define QQ_PAD_HOR 0
#define QQ_PAD_VER 0
#define QQ_BACK_IMG_PAD_LEFT 0
#endif

#define QQ_VOICE_MSG_MAX_RECORD_DURATION 8
#define QQ_VOICE_MSG_MAX_RECORD_SIZE QQ_VOICE_MSG_MAX_RECORD_DURATION * HAL_AMR_BUFSIZE_PER_SECOND + VOICE_MSG_AMR_HEAD_SIZE
#define MMI_QQ_QUERY_QR_TIME_INTERVAL 1000
#define MMI_QQ_GET_RECENT_MSG_CNT   10
#define MMI_QQ_GET_RECENT_MSG_TIME  2 * 24 * 3600
#define MMI_QQ_GET_FRIEND_CNT_ONCE  10
#define MMI_QQ_GET_FRIEND_MSG_ONCE  20
#define MMI_QQ_GET_VALID_MSG_CNT    10
#define MMI_QQ_EXPRESSION_MAX_CNT   18
#define MMI_QQ_CHAT_MSG_BTN_MAX_CNT 20

#define QQ_COLOR_TEXT_LIGHT     LV_COLOR_MAKE(0xE4, 0xFB, 0xFF)
#define QQ_COLOR_TEXT_DARK      LV_COLOR_MAKE(0x18, 0x3E, 0x7C)
#define QQ_COLOR_BLUE_NORMAL    LV_COLOR_MAKE(0x00, 0xCA, 0xF7)
#define QQ_COLOR_BLUE_PRESSED   LV_COLOR_MAKE(0x00, 0xB5, 0xE2)
#define QQ_COLOR_RED_NORMAL     LV_COLOR_MAKE(0xFA, 0x5F, 0x4B)
#define QQ_COLOR_RED_PRESSED    LV_COLOR_MAKE(0xD9, 0x4B, 0x3A)
#define QQ_COLOR_GREEN_NORMAL   LV_COLOR_MAKE(0x00, 0xD9, 0x6D)
#define QQ_COLOR_GREEN_PRESSED  LV_COLOR_MAKE(0x00, 0xC2, 0x61)
#define QQ_COLOR_MY_BUBBLE      LV_COLOR_MAKE(0x4B, 0xAE, 0xFF)
#define QQ_COLOR_FRIEND_BUBBLE  LV_COLOR_MAKE(0xE6, 0xE6, 0xE6)
#define QQ_COLOR_BG_GRAY        LV_COLOR_MAKE(0x40, 0x40, 0x40)

#define QQ_QR_PATH  "C:/qr_code.png"

/*bit for free num(0 - 31 bit) in lv_obj_t:  msg seq_id (15-31), unload flag (6) sending flag(5), direction(4), msg type(0 - 3)*/
#define QQ_MSG_SET_SEQ_ID(free_num, seq_id)      (free_num += seq_id << 16)   /*seq id: 16 bits*/
#define QQ_MSG_GET_SEQ_ID(free_num)             ((uint16_t)(free_num >> 16)) /*seq id: 16 bits*/
#define QQ_MSG_SET_LOCAL_FLAG(free_num)        (free_num |= (1 << 7))
#define QQ_MSG_IS_LOCAL_FLAG(free_num)         ((free_num & (1 << 7)) ? true : false)
#define QQ_MSG_SET_UNLOAD_FLAG(free_num)        (free_num |= (1 << 6))
#define QQ_MSG_IS_UNLOAD_FLAG(free_num)         ((free_num & (1 << 6)) ? true : false)
#define QQ_MSG_CLEAR_UNLOAD_FLAG(free_num)      (free_num &= ~(1 <<6))
#define QQ_MSG_SET_SENDING_FLAG(free_num)       (free_num |= (1 << 5))
#define QQ_MSG_IS_SENDING_FLAG(free_num)        ((free_num & (1 << 5)) ? true : false)
#define QQ_MSG_CLEAR_SENDING_FLAG(free_num)     (free_num &= ~(1 << 5))
#define QQ_MSG_SET_MSG_FROM_SERVICE(free_num)   (free_num |= (1 << 4))
#define QQ_MSG_IS_MSG_FROM_SERVICE(free_num)    ((free_num & (1 << 4)) ? true : false)
#define QQ_MSG_SET_MSG_TYPE(free_num, msg_type) (free_num += msg_type)      /*qq_msg_type_t: 4 bits*/
#define QQ_MSG_GET_MSG_TYPE(free_num)           ((uint8_t)(free_num & 0xF)) /*qq_msg_type_t: 4 bits*/

/**********************
 *      TYPEDEFS
 **********************/
typedef struct {
    lv_watch_obj_ext_t lv_watch_obj;
    /*New data for this type */
    lv_ll_t getdata_ll;
    lv_obj_t * leds_content;
    lv_obj_t * login;
    lv_obj_t * qr_bg_cont;
    lv_obj_t * recentmsg;
    lv_obj_t * friend;
    lv_obj_t * mine;
    lv_obj_t * msg_list;
    lv_obj_t * name;
    lv_obj_t * recent_list;
    lv_obj_t * friend_list;
    lv_obj_t * friend_list_act_btn;
    uint8_t login_state; //0--login  1--logout
    uint8_t new_msg_type;
} lv_qq_obj_ext_t;

typedef struct {
    lv_list_ext_t old_ext;
    /*New data for this type */
    uint8_t * buffer; //record buffer
    lv_obj_t * record_cont;
    lv_anim_t voice_playing_anim;
    bool pressing;
    bool getting_msg;
    MCI_EVNET_T event;
    uint8_t btn_cnt;
} qq_msg_list_ext_t;

typedef struct {
    lv_img_ext_t img_ext;
    /*New data for this type */
    char * url;
    uint8_t * voice_buffer;
    uint32_t voice_size;
} qq_msg_voice_obj_ext_t;

typedef struct {
    lv_btn_ext_t btn_ext;
    /*New data for this type */
    char openid[64];
    char qqid[QQ_ID_LEN];
    uint32_t main_sourceid;
    uint8_t reqtype;
} qq_validmsg_btn_ext_t;

typedef struct {
    lv_btn_ext_t btn_ext;
    /*New data for this type */
    watch_qq_user_info_t info;
} qq_friend_btn_ext_t;

typedef struct {
    char         openid[64];
    uint32_t     time;
} qq_contact_info_t;

enum
{
    QQ_MSG_TYPE_TEXT = 0,
    QQ_MSG_TYPE_VOICE,
    QQ_MSG_TYPE_EXPRESSION,
    QQ_MSG_TYPE_PHOTO,
    QQ_MSG_TYPE_TIME,
    QQ_MSG_TYPE_OTHER,
};
typedef uint8_t qq_msg_type_t;

typedef struct {
    qq_msg_type_t type;
    uint32_t time;
    void * data;                 /*file path string if size is 0, otherwise data buffer*/
    uint32_t size;
    uint16_t seq_id;
    uint8_t sending;             /*for send msg 1--sending; 0--sent*/
    uint8_t duration;            /*for voice msg*/
    uint8_t local_msg;           /*for voice msg: 0 -- online; 1-- local*/
    uint8_t ex_index;            /*for expression msg*/
    uint8_t direction;           /*1-- from other; 0--from self*/
} qq_msg_desc_t;

enum {
    QQ_HEAD_TYPE_PNG = 0,
    QQ_HEAD_TYPE_JPG,
    QQ_HEAD_TYPE_OTHER,
};
typedef uint8_t qq_head_img_type;

enum {
    LIST_TYPE_RECENT_CONTACTS = 0,
    LIST_TYPE_FUNCTION,
    LIST_TYPE_MY_FRIENDS,
    LIST_TYPE_VALIDATION_MSG,
};
typedef uint8_t qq_list_type;

enum {
    QQ_QRCODE = 1,
    QQ_FRIEND_LIST,
    QQ_FRIEND_INFO,
    QQ_SEARCH_FRIEND_INFO,
    QQ_INPUT_NUM,
    QQ_VALID_MSG,
    QQ_VALID_MSG_DETAIL,
    QQ_CHAT,
    QQ_EXPRESSION,
};
typedef uint8_t qq_back_img_type;

enum
{
    QQ_GET_MY_INFO = 0,
    QQ_FIND_FRIEND_INFO,
    QQ_GET_FRIEND_INFO,
    QQ_GET_VALIDMSG_INFO,
    QQ_GET_LIST_FRIEND_INFO,
};
typedef uint8_t qq_get_friend_info_type;

enum
{
    QQ_DATA_QR = 0,
    QQ_DATA_MY_HEAD,
    QQ_DATA_FRIEND_HEAD,
    QQ_DATA_MSG_VOICE,
    QQ_DATA_MSG_PIC,
    QQ_DATA_VALID_FRIEND_HEAD,
};
typedef uint8_t qq_get_data_type;

enum
{
    QQ_NEW_MSG = 0,
    QQ_NEW_FRIEND,
};
typedef uint8_t qq_new_msg_type_t;

typedef struct {
    uint8_t data_type;
    uint8_t index; //for type is QQ_DATA_MSG_PIC and QQ_DATA_MSG_VOICE
    char * url;
} qq_get_data_info_t;

enum {
    MMI_QQ_QUERY_QR_CNF = UI_MSG_QQ_ADP_BASE,//0x400
    MMI_QQ_GET_QR_CNF,
    MMI_QQ_REGISTER_CNF,
    MMI_QQ_GET_MSG_CNF,
    MMI_QQ_SEND_MSG_CNF,
    MMI_QQ_GET_FRIEND_MSG_CNF,
    MMI_QQ_GET_FRIEND_LIST_CNF,
    MMI_QQ_GET_FRIEND_INFO_CNF,
    MMI_QQ_GET_RECENT_CONTACT_CNF,
    MMI_QQ_FIND_FRIEND_CNF,
    MMI_QQ_ADD_FRIEND_CNF,
    MMI_QQ_ACK_ADD_FRIEND_CNF,
    MMI_QQ_DELETE_FRIEND_CNF,
    MMI_QQ_GET_UNDECIDED_CNF,
    MMI_QQ_MSG_READ_CNF,
    MMI_QQ_GET_DATA_CNF,
    MMI_QQ_NEW_MSG_NOTIFY,
};

typedef struct
{
    UI_Inter_Msg_Header_t header;
    uint8_t result;
} mmi_msg_qq_cnf_t;

typedef struct
{
    UI_Inter_Msg_Header_t header;
    uint8_t result;
    uint32_t time;
    uint16_t msg_seqid;
} mmi_msg_qq_seng_msg_cnf_t;

typedef struct
{
    UI_Inter_Msg_Header_t header;
    watch_qq_get_qr_cnf_t * get_qrcnf;
} mmi_msg_qq_get_qr_cnf_t;


typedef struct
{
    UI_Inter_Msg_Header_t header;
    watch_qq_query_qr_cnf_t * query_qrcnf;
} mmi_msg_qq_query_qr_cnf_t;

typedef struct
{
    UI_Inter_Msg_Header_t header;
    uint8_t result;
    char openid[64];
} mmi_msg_qq_find_friend_cnf_t;

typedef struct
{
    UI_Inter_Msg_Header_t header;
    watch_qq_get_friend_info_cnf_t * get_friendcnf;
} mmi_msg_qq_get_friend_info_cnf_t;

typedef struct
{
    UI_Inter_Msg_Header_t header;
    watch_qq_get_msg_cnf_t * get_msgcnf;
} mmi_msg_qq_get_msg_cnf_t;

typedef struct
{
    UI_Inter_Msg_Header_t header;
    watch_qq_get_friend_msg_cnf_t * get_friend_msgcnf;
} mmi_msg_qq_get_friend_msg_cnf_t;

typedef struct
{
    UI_Inter_Msg_Header_t header;
    watch_qq_get_friend_list_cnf_t * friend;
} mmi_msg_qq_get_friend_list_cnf_t;

typedef struct
{
    UI_Inter_Msg_Header_t header;
    watch_qq_get_recent_contact_cnf_t * get_recent_contactcnf;
} mmi_msg_qq_get_recent_contact_cnf_t;

typedef struct
{
    UI_Inter_Msg_Header_t header;
    watch_qq_get_undecided_cnf_t * get_undecidedcnf;
} mmi_msg_qq_get_undecided_cnf_t;

typedef struct
{
    UI_Inter_Msg_Header_t header;
    watch_qq_get_data_cnf_t * get_datacnf;
} mmi_msg_qq_get_data_cnf_t;

typedef struct
{
    UI_Inter_Msg_Header_t header;
    uint8_t msg_type;
} mmi_msg_qq_new_msg_notify_t;

/**********************
 * GLOBAL PROTOTYPES
 **********************/
//qq_main.c
void qq_create_event_cb(lv_obj_t * btn, lv_event_t e);
void qq_back_img_event_cb(lv_obj_t * img, lv_event_t event);
lv_obj_t * qq_get_obj(void);
lv_qq_obj_ext_t * qq_get_ext(void);
lv_obj_t * qq_list_add(lv_obj_t * list, void * img_src, char * text, void * param, qq_list_type type);
lv_obj_t * qq_create_list(lv_obj_t * par);
lv_obj_t * qq_create_bg_cont(lv_obj_t * par, lv_opa_t opa, uint16_t txtId);
lv_obj_t * qq_create_msgbox(lv_obj_t * par, uint16_t txtId, lv_event_cb_t cb);
lv_obj_t * qq_create_back_img(lv_obj_t * par, qq_back_img_type type);
lv_obj_t * qq_tileview_add_tile(lv_obj_t * tileview, uint16_t id);
void qq_set_get_friend_info_type(uint8_t type);
void qq_update_friend_info(watch_qq_user_info_t * info);
void qq_add_get_data_info(uint8_t type, uint8_t index, char * url);
void qq_show_data(watch_qq_get_data_cnf_t * data);
void qq_get_timestr_from_timestamp(uint32_t timestamp, char * timestr, uint8_t len);
uint8_t qq_get_voice_duration(char * data, uint32_t data_size);
bool watch_is_qq_activity(void);
lv_obj_t * qq_create_new_message(lv_obj_t * activity_obj, uint8_t msg_type);
void watch_qq_reset_get_msg_flag(void);

//qq_add_friend.c
void qq_get_friend_info(char * open_id);
void qq_add_friend_req_result(uint8_t result);
void qq_create_add_friend(void);
void qq_show_find_friend_failed(void);
void qq_show_friend_info(watch_qq_user_info_t * info);

//qq_login.c
void qq_create_no_network(lv_obj_t * par);
void qq_create_scan_login(void);
void qq_destroy_login(void);
void qq_create_main(void);
void qq_show_login(void);
void qq_show_qrcode(void * src);
void qq_update_qrcode(uint8_t query_res, char * openid, char * access_token);
void qq_create_get_qr_failed(void);
void qq_logout_btn_event_cb(lv_obj_t * btn, lv_event_t event);
void qq_create_switch_account(void);
void qq_show_login_failed(void);

//qq_recent_msg.c
void qq_create_recent_contacts_list(lv_ll_t * recent_info_ll);
void qq_no_msg_recently(void);
void qq_get_recent_contact(void);
void qq_show_chat_new_message(watch_qq_get_msg_cnf_t * get_msgcnf);
void qq_get_msg(void);
void qq_free_my_cookie(void);
void qq_delete_recent_contact(lv_obj_t * list, char * openid);
void qq_get_new_message(void);
void qq_init_contact_list(void);
void qq_clear_contact_list(void);

//qq_validation_msg.c;
void qq_create_validation_msg_list(watch_qq_undecided_msg_successread_t * msg);
void qq_validation_msg_detail_show(watch_qq_user_info_t * info);
uint16_t qq_get_txtId_from_reqtype(uint8_t reqtype);
void qq_validation_new_msg_tip(void);
void qq_validation_msg_detail_update_headimg(void * src);

//qq_friend_msg.c
void qq_create_friends_list(watch_qq_get_friend_list_cnf_t * friend);
void qq_get_my_friend_list(void);
void qq_my_friend_list_btn_event_cb(lv_obj_t * btn, lv_event_t event);
void qq_friend_info_update(watch_qq_user_info_t * info);
void qq_del_friend_result(uint8_t result);
void qq_add_msg_into_list(lv_ll_t * msg_infos_ll);
void qq_send_msg_result(uint8_t result, uint32_t time, uint16_t seqid);
void qq_create_chat(lv_obj_t * par, watch_qq_user_info_t * info);
qq_friend_btn_ext_t * qq_btn_allocate_ext(lv_obj_t * btn, watch_qq_user_info_t * node);
void qq_friend_info_update_headimg(void * src);
void qq_get_msg_over(uint32_t time, uint32_t random);
void qq_friend_list_update_img_head(void);
bool qq_list_obj_is_label(lv_obj_t * obj);
void qq_play_voice(lv_obj_t * img, qq_msg_list_ext_t * list_ext);
void qq_stop_play_voice(lv_qq_obj_ext_t * ext);
void qq_stop_record(lv_qq_obj_ext_t * ext);

#if QQ_UI_TEST
void qq_find_friend_result_timer_cb(void * param);
void qq_add_friend_timer_cb(void * param);
void qq_show_friend_info_timer_cb(void * param);
void qq_phone_confirm_timer_cb(void * param);
void qq_scan_sucess_timer_cb(void * param);
void qq_invalid_qrcode_timer_cb(void * param);
void qq_show_qrcode_timer_cb(void * param);
void qq_login_img_destroyed_timer_cb(void * param);
void qq_logging_out_timer_cb(void * param);
void qq_get_friends_timer_cb(void * param);
void qq_get_friend_info_timer_cb(void * param);
void qq_delete_friend_timer_cb(void * param);
void qq_get_validmsg_timer_cb(void * param);
void qq_validation_msg_detail_timer_cb(void * param);
void qq_get_msg_timer_cb(void * param);
void qq_send_msg_timer_cb(void * param);
#endif
/**********************
 *      MACROS
 **********************/

#endif /*USE_LV_WATCH_QQ*/

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /*QQ_H*/
